package com.dy.jpa.untils;

public class TestObject {
    public class StringFoo {
        private String x;

        public StringFoo(String x) {
            this.x = x;
        }

        public String getX() {
            return x;
        }

        public void setX(String x) {
            this.x = x;
        }
    }

    public class DoubleFoo {
        private Double x;

        public DoubleFoo(Double x) {
            this.x = x;
        }

        public Double getX() {
            return x;
        }

        public void setX(Double x) {
            this.x = x;
        }
    }

    /**
     * 该方法为上面两个的重构 StringFoo DoubleFoo 使用Object的方法重构
     */
    public static class ObjectFoo {
        private Object x;

        public ObjectFoo(Object x) {
            this.x = x;
        }

        public Object getX() {
            return x;
        }

        public void setX(Object x) {
            this.x = x;
        }
    }

    public static class ObjectFooDemo {
        public static void main(String args[]) {
            ObjectFoo strFoo = new ObjectFoo(new String("Hello Generics!"));
            ObjectFoo douFoo = new ObjectFoo(new Double(new Double("33")));
            ObjectFoo objFoo = new ObjectFoo(new Object());
            System.out.println("strFoo.getX=" + (String) strFoo.getX());
            System.out.println("douFoo.getX=" + (Double) douFoo.getX());
            System.out.println("objFoo.getX=" + objFoo.getX());
        }
        /**
         * strFoo.getX=Hello Generics!
         * douFoo.getX=33.0
         * objFoo.getX=java.lang.Object@448139f0
         */
    }

    static class GenericsFoo<T> {
        private T x;

        public GenericsFoo(T x) {
            this.x = x;
        }

        public T getX() {
            return x;
        }

        public void setX(T x) {
            this.x = x;
        }
    }

    public static class GenericsFooDemo {
        public static void main(String args[]) {
            GenericsFoo<String> strFoo = new GenericsFoo<String>("Hello Generics!");
            GenericsFoo<Double> douFoo = new GenericsFoo<Double>(new Double("33"));
            GenericsFoo<Object> objFoo = new GenericsFoo<Object>(new Object());
            System.out.println("strFoo.getX=" + strFoo.getX());
            System.out.println("douFoo.getX=" + douFoo.getX());
            System.out.println("objFoo.getX=" + objFoo.getX());
        }
        /**
         * strFoo.getX=Hello Generics!
         * douFoo.getX=33.0
         * objFoo.getX=java.lang.Object@448139f0
         * 和使用“Object泛型”方式实现结果的完全一样，但是这个Demo简单多了，里面没有强制类型转换信息。
         * 下面解释一下上面泛型类的语法：
         * 使用<T>来声明一个类型持有者名称，然后就可以把T当作一个类型代表来声明成员、参数和返回值类型。
         * 当然T仅仅是个名字，这个名字可以自行定义。
         * class GenericsFoo<T> 声明了一个泛型类，这个T没有任何限制，实际上相当于Object类型，实际上相当于 class GenericsFoo<T extends Object>。
         * 与Object泛型类相比，使用泛型所定义的类在声明和构造实例的时候，可以使用“<实际类型>”来一并指定泛型类型持有者的真实类型。类如
         * GenericsFoo<Double> douFoo=new GenericsFoo<Double>(new Double("33"));
         * 当然，也可以在构造对象的时候不使用尖括号指定泛型类型的真实类型，但是你在使用该对象的时候，就需要强制转换了。比如：GenericsFoo douFoo=new GenericsFoo(new Double("33"));
         * 实际上，当构造对象时不指定类型信息的时候，默认会使用Object类型，这也是要强制转换的原因。
         */
    }
}
